package cn.slg.module.system.service.pk.utils;

import cn.slg.module.system.dal.dataobject.group.Group;
import cn.slg.module.system.dal.dataobject.wujiang.WuJiangDO;
import cn.slg.module.system.service.pk.skill.SKillCount;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.function.Supplier;

import static cn.slg.module.system.service.pk.utils.Print.formatStringPrint;
import static cn.slg.module.system.service.pk.utils.Print.percentInstance;

// 各种显示信息
public class Show {



    // [攻击者]对[目标]发动普通攻击
    public static void showNormalAttack(WuJiangDO attacker, WuJiangDO target) {
        // 显示 [攻击者]对[目标]发动普通攻击\n
        String str1 = spacing1() + showBingAndName(attacker) +
                "对" + showName(target) +
                "发动普通攻击" + "\n";
        formatStringPrint(str1, 29, 0);
    }

    // 普通攻击造成伤害时，显示信息
    // [被攻击者名字]损失了兵力数值(剩余兵力)
    public static void normalAttackHarmShow(WuJiangDO target, Short harm) {

        // 显示信息
        formatStringPrint(spacing2() + showName(target)
                + "损失了兵力" + harm + parcel2(target.getBingLi())
                + "\n", 29, 0);
    }


    // [武将名]发动战法【战法名】
    public static void skillNameShow(WuJiangDO self, String skillName) {
        String show = spacing1() + showBingAndName(self) +
                "发动战法" + "【" + skillName + "】" + "\n";
        formatStringPrint(show, 29, 0);

        // 这里显示战法名的时候，就证明该战法被发动了，累计发动次数
        SKillCount sKillCount = self.getSkillCount().get(skillName);
        sKillCount.setTimes((byte) (sKillCount.getTimes() + 1));
    }

    public static void prepareSkillShow(WuJiangDO self, String skillName) {
        String show = spacing1() + showBingAndName(self) +
                "准备发动" + "【" + skillName + "】" + "\n";
        formatStringPrint(show, 29, 0);
    }

    // 技能直接造成伤害时，显示信息
    // [被攻击者名字]由于[攻击者名字]【战法名】的伤害,损失了兵力数值(剩余兵力)
    public static void skillHarmShow(WuJiangDO attacker, WuJiangDO target, String skillName, Short harm) {

        String show = spacing2() + showName(target) + "由于" + showName(attacker)
                + parcel1(skillName) + "的伤害,损失了兵力" + harm + parcel2(target.getBingLi()) + "\n";
        formatStringPrint(show, 29, 0);
    }

    // 持续性状态造成伤害时，显示信息
    // [被施加者的名字]由于[施加者的名字]的【战法名】的【状态名】,损失了兵力数值(剩余兵力)
    public static void stateHarmShow(WuJiangDO inflictor, WuJiangDO receiver, String skillName, String stateName, Short harm) {
        String show = spacing2() + showName(receiver) + "由于" + showName(inflictor) + "的" +
                parcel1(skillName) + "的" + parcel1(stateName) + "，损失了" + harm + parcel2(receiver.getBingLi()) + "\n";
        formatStringPrint(show, 29, 0);
    }


    /**
     * 被施加属性状态时显示，
     * @param target      被施加者
     * @param stateEffect 属性状态效果描述
     * @param isPercent   是百分数（比如伤害提升百分之多少）还是浮点数（比如属性数值提升多少）
     * @param effectRate  百分数或者浮点数
     * @param supplier    提供能够获取 该状态影响被施加者后的某个属性的值
     */
    public static void propertyStateShow(WuJiangDO target, String stateEffect, Boolean isPercent, Float effectRate, Supplier<Float> supplier) {
        Float v = supplier.get();
        System.out.println(spacing2() + showName(target) + stateEffect + parcel2(isPercent ? percentInstance.format(effectRate) : effectRate) + parcel2(isPercent ? percentInstance.format(v) : v));
    }

    //        System.out.printf("%-10s%-10s%-10d\n","Number1","Number2",num1);
    public static void countShow(Group firstGroup, Group secondGroup) {
        System.out.println("\n\n战斗结束,开始结算**********");
        System.out.printf("\t%-16s%-12s%-14s%-16s%-14s%-14s%-12s%-16s%-16s\n", "武将", "普攻杀敌", "战法杀敌", "救援", "损失", "死兵", "本场伤兵", "累计伤兵", "剩余兵力");
        countShow(firstGroup);
        countShow(secondGroup);

        System.out.println("\n\n统计战法信息*********");
        skillCount(firstGroup);
        skillCount(secondGroup);
    }

    // 实现字符串对齐效果
    private static String align(String input, int longth) {
        return input;
    }

    private static void skillCount(Group group) {
        group.getAllGroup().stream().forEach(wuJiangDO -> {
            Map<String, SKillCount> skillHarmCount = wuJiangDO.getSkillCount();
            skillHarmCount.values().forEach(sKillCount -> {

                System.out.println(
                        String.format("%-8s", showName(wuJiangDO))
                                // + parcel1(sKillCount.getSkillName())
                                + String.format("%-12s", parcel1(sKillCount.getSkillName()))
                                + "发动" + parcel2(sKillCount.getTimes())
                                + "杀敌" + parcel2(sKillCount.getHarm())
                                + "救援" + parcel2(sKillCount.getRescue()));
            });
            System.out.println();
        });
    }


    private static void countShow(Group group) {
        group.getAllGroup().stream().forEach(wuJiangDO -> {
            System.out.printf("\t%-16s%-16d%-16d%-16d%-16d%-16d%-16d%-16d%-16d\n", wuJiangDO.getName(), wuJiangDO.getTotalAttackHarm(),
                    wuJiangDO.getTotalSkillHarm(), wuJiangDO.getTotalCure(), wuJiangDO.getTotalLoss(), wuJiangDO.getTotalDie(), wuJiangDO.getTotalWounded(),
                    wuJiangDO.getAccumWounded(), wuJiangDO.getBingLi());
        });
    }

    public static String showBingAndName(WuJiangDO wuJiangDO) {
        return wuJiangDO.getBingZhong() + "[" + wuJiangDO.getUserId() + "+" + wuJiangDO.getName() + "]";
    }

    public static String showName(WuJiangDO wuJiangDO) {
        // [武将名]
        return "[" + wuJiangDO.getUserId() + "+" + wuJiangDO.getName() + "]";
    }

    // 【技能名】或   【状态名】
    public static String parcel1(String str) {
        return "【" + str + "】";
    }

    // 包裹伤害值、剩余兵力数
    public static String parcel2(Object str) {
        return "(" + str + ")";
    }


    // 一级缩进 （***开始行动）
    public static String spacing1() {
        return String.format("%" + (8) + "s", "");
    }

    // 二级缩进
    public static String spacing2() {
        return String.format("%" + (18) + "s", "");
    }
}
